package com.wangp.mywrite.coding;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/***
 * @author wangpeng
 * @since 2022-02-22  16:04
 *
 * 1,2,...9 9个数。组成三个三位数，使得比例为 A:B:C
 *
 * 例如：输入 A:B:C 为 1:2:3
 * 输出结果：192 384 576
 * 输出结果：219 483 657
 * 输出结果：273 546 819
 * 输出结果：327 654 981
 */
public class TripleHit {

    public static void main(String[] args) {
        TripleHit tripleHit = new TripleHit();
//        for (int i = 1; i < 10; i++) {
//            for (int j = 1; j < 10; j++) {
//                for (int k = 1; k < 10; k++) {
//                    if (i == j) {
//                        break;
//                    }
//                    if (j == k || i == k) {
//                        continue;
//                    }
//                    List<List<Integer>> hit = tripleHit.hit(Arrays.asList(i, j, k));
//                    if (!CollectionUtils.isEmpty(hit)) {
//                        System.out.println("i=" + i + ",j=" + j + ",k=" + k);
//                    }
//                }
//            }
//        }
        long start = System.currentTimeMillis();
        System.out.println(tripleHit.hit(Arrays.asList(1, 2, 3)));
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        System.out.println(tripleHit.hit2(Arrays.asList(1, 2, 3)));
        end = System.currentTimeMillis();
        System.out.println(end - start);


        start = System.currentTimeMillis();
        System.out.println(tripleHit.hit3(Arrays.asList(1, 2, 3)));
        end = System.currentTimeMillis();
        System.out.println(end - start);

    }

    /**
     * @param scale 比例，如：1,2,3 代表 1:2:3
     */
    public List<List<Integer>> hit(List<Integer> scale) {
        List<List<Integer>> res = new ArrayList<>();
        int A = scale.get(0);
        int B = scale.get(1);
        int C = scale.get(2);
        for (int i = 123; i < 999; i++) {
            for (int j = 333; j < 666; j++) {
                for (int k = 123; k < 999; k++) {
                    if (i == j) {
                        break;
                    }
                    if (j == k || i == k) {
                        continue;
                    }
                    if (k == C * i / A && j == B * i / A && isSingleNum(i, j, k)) {
                        List<Integer> tmp = Arrays.asList(i, j, k);
                        res.add(tmp);
                    }
                }
            }
        }
        return res;
    }

    public List<List<Integer>> hit2(List<Integer> scale) {
        List<List<Integer>> res = new ArrayList<>();
        int A = scale.get(0);
        int B = scale.get(1);
        int C = scale.get(2);
        for (int i = 100; i < 333; i++) {
            for (int j = 100; j < 987; j++) {
                for (int k = 100; k < 987; k++) {
                    if (i == j) {
                        break;
                    }
                    if (j == k || i == k) {
                        continue;
                    }
                    if (k == C * i / A && j == B * i / A && isSingleNum(i, j, k)) {
                        List<Integer> tmp = Arrays.asList(i, j, k);
                        res.add(tmp);
                    }
                }
            }
        }
        return res;
    }

    public List<List<Integer>> hit3(List<Integer> scale) {
        int A = scale.get(0);
        int B = scale.get(1);
        int C = scale.get(2);
        int[] arr = new int[10];
        Arrays.fill(arr, 0);
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 123; i < 329; i++) {
            int two = i * B / A;
            int three = i * C / A;

            if (isRepeatNum(i)) {
                continue;
            }
            if (isRepeatNum(two)) {
                continue;
            }
            if (isRepeatNum(three)) {
                continue;
            }
            arr[i / 100] = 1;
            arr[i / 10 % 10] = 1;
            arr[i % 10] = 1;
            if (isUsedNum(arr, i, two)) {
                continue;
            } else {
                arr[two / 100] = 1;
                arr[two / 10 % 10] = 1;
                arr[two % 10] = 1;
            }
            if (isUsedNum(arr, i, three)) {
                arr[two / 100] = 0;
                arr[two / 10 % 10] = 0;
                arr[two % 10] = 0;
                continue;
            }else {
                res.add(Arrays.asList(i,two,three));
            }
            arr[i / 100] = 0;
            arr[(i / 10) % 10] = 0;
            arr[i % 10] = 0;
            arr[two / 100] = 0;
            arr[(two / 10) % 10] = 0;
            arr[two % 10] = 0;
        }
        return res;
    }

    private boolean isUsedNum(int[] arr, int i, int num) {
        if (arr[num / 100] == 1 || arr[num / 10 % 10] == 1 || arr[num % 10] == 1) {
            arr[i / 100] = 0;
            arr[i / 10 % 10] = 0;
            arr[i % 10] = 0;
            return true;
        }
        return false;
    }

    private boolean isRepeatNum(int num) {
        int hundred = num / 100;
        int ten = (num / 10) % 10;
        int single = num % 10;
        return hundred == ten || hundred == single || ten == single || hundred == 0 || ten == 0 || single == 0;
    }

    private boolean isSingleNum(int i, int j, int k) {
        int[] arr = new int[10];
        Arrays.fill(arr, -1);

        return !checkNum(i, arr) && !checkNum(j, arr) && !checkNum(k, arr);
    }

    private boolean checkNum(int i, int[] arr) {
        List<Integer> list = parseInt(i);
        for (Integer num : list) {
            if (0 == num) {
                return true;
            }
            if (arr[num] == -1) {
                arr[num] = num;
            } else {
                return true;
            }
        }
        return false;
    }

    private List<Integer> parseInt(int i) {
        int a = i % 10;
        int b = i / 10 % 10;
        int c = i / 100 % 10;
        return Arrays.asList(a, b, c);
    }


}
